package com.pi.smart.base.task.processor;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.pi.base.util.lang.IntegerUtil;
import com.pi.base.util.time.DateTools;
import com.pi.dc.model.DcBedStatusPostForm;
import com.pi.dc.service.DcBedService;
import com.pi.dc.service.HcUserSleepLogService;
import com.pi.smart.base.task.UserSleepLogTask;
import com.pi.smart.client.ins.bed.annotation.ForBedIns;
import com.pi.smart.client.ins.bed.category.BedInsEnum;
import com.pi.smart.client.ins.bed.domain.SmartBedCmd;
import com.pi.smart.client.ins.bed.domain.SmartBedRoutineResponse;
import com.pi.smart.client.ins.bed.variety.BedInsHandler;

@ForBedIns(ins = BedInsEnum.SLEEP_STATUS)
@Component
public class SleepStatusProcessor implements BedInsHandler{
  
  private static final Logger logger = LoggerFactory.getLogger(UserSleepLogTask.class);
  
  @Autowired
  private HcUserSleepLogService userSleepLogService;
  @Autowired
  private DcBedService dcBedService;
  
  @Override
  public void process(SmartBedCmd cmd) {
    if(null == cmd)
      return;
    try{
      handle(cmd);
    }catch(Exception e){
      logger.error("处理被子的实时状态数据失败", e);
    }
  }
  
  private void handle(SmartBedCmd cmd){
    byte[] ins = cmd.getCmd();
    logger.info("接收到开机数据, 设备编号:{}, 数据长度: {}, 温度:{}, 湿度:{}, 电压: {}",
        cmd.getDevCode(), ins[9], ins[10], ins[11], ins[12]);
    
    if((cmd.getCmd()[0] & 0xFF)  == 0xFE && ((cmd.getCmd()[1] & 0xFF) == 0x01 || (cmd.getCmd()[1] & 0xFF) == 0x09)){
      handleNewSleepStatus(cmd);
    }else {
      SmartBedRoutineResponse response = new SmartBedRoutineResponse();
      response.setDevId(cmd.getDevCode());
      response.setHumidity(cmd.getCmd()[11] & 0XFF);
      response.setMessageId(cmd.getMessageId());
      response.setTemper(cmd.getCmd()[10] & 0XFF);
      response.setTs(cmd.getTs());
      response.setVoltage(cmd.getCmd()[12] & 0xFF);
      handleSingleSleepStatus(response);
    }

  }
  
  private void handleNewSleepStatus(SmartBedCmd cmd) {
    int totalLength = ((cmd.getCmd()[3] & 0xFF) << 8) + (cmd.getCmd()[4] & 0xFF);
    int length = (totalLength - 13)/3;
    if(length > 0) {
      int voltage = cmd.getCmd()[13 + (length * 3)] & 0xFF;
      List<SmartBedRoutineResponse> responseList = new ArrayList<>(length);
      Long ts = length > 1 ? DateTools.getDateBegin(new Date()).getTime() - 2 * 3600000:cmd.getTs();
      for(int i =0; i< length; i++) {
        SmartBedRoutineResponse response = new SmartBedRoutineResponse();
        response.setDevId(cmd.getDevCode());
        response.setMessageId(cmd.getMessageId());
        response.setTs(ts + 3600000 * i);
        response.setVoltage(voltage);
        response.setTemper(cmd.getCmd()[13 + (i * 3) ] & 0XFF);
        response.setHumidity(cmd.getCmd()[14 + (i * 3)] & 0XFF);
        response.setRollingTimes(cmd.getCmd()[15 + (i * 3) ] & 0XFF);
        responseList.add(response);
      }
      handleSleepStatus(responseList);
    }
  }

  private void handleSingleSleepStatus(SmartBedRoutineResponse response) {
    userSleepLogService.insertUserSleepRollLog(response.getDevId(), response.getTs());
    DcBedStatusPostForm form = new DcBedStatusPostForm();
    form.setBatteryStatus(response.getVoltage());
    form.setDeviceCode(response.getDevId());
    form.setRelativeHumidity(response.getHumidity());
    form.setTemperature(response.getTemper());
    dcBedService.updateDeviceBattery(form);
  }
  
  private void handleSleepStatus(List<SmartBedRoutineResponse> responseList) {
    if(CollectionUtils.isEmpty(responseList)) {
      return;
    }
    userSleepLogService.insertUserSleepRollLogBatch(responseList);
    int maxIndex = responseList.size() - 1;
    DcBedStatusPostForm form = new DcBedStatusPostForm();
    form.setBatteryStatus(responseList.get(0).getVoltage());
    form.setDeviceCode(responseList.get(0).getDevId());
    form.setRelativeHumidity(responseList.get(maxIndex).getHumidity());
    form.setTemperature(responseList.get(maxIndex).getTemper());
    dcBedService.updateDeviceBattery(form);
  }
}
